<?php

declare(strict_types=1);

namespace App\Common\Task;

use App\System\Model\Debug;
use Hyperf\Amqp\Message\ProducerMessageInterface;
use Hyperf\Di\Annotation\AnnotationCollector;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Amqp\Producer;
use Mine\Amqp\Event\BeforeProduce;
use Psr\EventDispatcher\EventDispatcherInterface;

/**
 * 公用投递任务
 */
class GraceTask extends BaseTask
{
    /**
     * 公用投递推进器
     * @return void
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public function push($message, $delayTime = 0)
    {
        // 延迟时间
        if ($delayTime > 0) {
            $message->setDelayMs($delayTime * 1000);
        }

        $this->injectMessageProperty($message);

        // 生产事件
        try {
            $eventDispatcher = ApplicationContext::getContainer()->get(EventDispatcherInterface::class);
            $eventDispatcher->dispatch(new BeforeProduce($message, $delayTime));
        } catch (\Throwable $e) {
            Debug::info($e->getFile() . $e->getLine() . $e->getMessage());
        }

        $producer = ApplicationContext::getContainer()->get(Producer::class);
        $producer->produce($message);
    }

    private function injectMessageProperty(ProducerMessageInterface $producerMessage)
    {
        if (class_exists(AnnotationCollector::class)) {
            /** @var null|\Hyperf\Amqp\Annotation\Producer $annotation */
            $annotation = AnnotationCollector::getClassAnnotation(get_class($producerMessage), \Hyperf\Amqp\Annotation\Producer::class);
            if ($annotation) {
                $annotation->routingKey && $producerMessage->setRoutingKey($annotation->routingKey);
                $annotation->exchange && $producerMessage->setExchange($annotation->exchange);
            }
        }
    }
}
